package com.example.coroutines

import kotlinx.coroutines.*
import org.junit.Test
import kotlin.coroutines.CoroutineContext


/**
 * 协程调度器测试
 *
 * @author zhouronghua
 * @time 2021/12/27 10:10 下午
 */
public class DispatchersTest {

    /**
     * 测试协程协程Main调度器
     *
     * @author zhouronghua
     * @time 2021/9/29 8:55 上午
     */
    @Test
    fun testDispatchersMain() {
        // runBlocking 启动的协程的调度器只能说调用者所在线程。
        runBlocking {
            // 主线程阻塞执行
            launch {
                println("main runBlocking in ${Thread.currentThread().name}")
            }
            // 非主线程执行(创建线程池执行任务)
            launch(Dispatchers.Default) {
                println("Dispatchers.Default in ${Thread.currentThread().name}")
            }
            // 无约束协程执行器
            launch(Dispatchers.Unconfined) {
                println("Dispatchers.Unconfined in ${Thread.currentThread().name}")
                delay(1200)   //恢复线程中的协程
                println("Dispatchers after.Unconfined in ${Thread.currentThread().name}")
            }
            // 启动一个单任务数线程池执行协程任务
            launch(newSingleThreadContext("NewThread")) {
                println("newSingleThreadContext in ${Thread.currentThread().name}")
            }
        }
    }

    /**
     * 切换线程执行协程任务
     * @author zhouronghua
     * @time 2021/12/27 10:10 下午
     */
    @Test
    fun testThreadSwitch() {
        println("newSingleThreadContext in ${Thread.currentThread().name}")
        newSingleThreadContext("Ctx1").use { ctx1 ->
            newSingleThreadContext("Ctx2").use { ctx2 ->
                // 在Ctx1线程执行协程
                runBlocking(ctx1) {
                    println("this is ctx1")
                    println("ctx1 newSingleThreadContext in ${Thread.currentThread().name}")
                    //切换线程到Ctx2继续执行协程，依然保持在另外一个协程中
                    withContext(ctx2) {
                        println("this is ctx2")
                        println("ctx2 newSingleThreadContext in ${Thread.currentThread().name}")
                    }
                }
            }
        }
    }

    /**
     * 测试在IO调度器切换主协程任务
     *
     */
    @Test
    fun testIODispatchCoroutine() {
        newSingleThreadContext("Ctx1").use { ctx1->
            // 新启动的子线程中执行
            println("ctx1 newSingleThreadContext in ${Thread.currentThread().name}")
            runBlocking(ctx1) {
                // 切换主线程阻塞执行
                println("this is ctx1 main in ${Thread.currentThread().name}")
                delay(1200)   //恢复线程中的协程
                // 恢复以后还是在主线程中runBlocking
                println("ctx1 recovery in ${Thread.currentThread().name}")
            }
        }
    }
}